www.gusucode.com > VC 2D游戏编辑器-源码程序 > VC 2D游戏编辑器-源码程序/code/game_Source/GameLib/Graphics/buffer_func.cpp

    //Download by http://www.NewXing.com
/////////////////
// buffer_func.h:	缓冲特效处理
//
// 版本0010		:	二零零三年七月四日
//
// written by	:	Huang LunXin
//
// Compiler		:	Visual C++ 6.0
//
// Copyright	:	IcePoint  2003
/////////////////
// 此文件用来处理屏幕特效
#include "draw_globle.h"
#include "buffer_func.h"
#include "..\\globle.h"
#include "..\\globle_func.h"
#include "..\\..\\logo.h"

int m_iScreenState;

bool InitRippleData();
void AddRippleSour(int cx,int cy,int nWeight,int nRad);
void ComputeNextRipple();
void RenderRipple();

//////////////////////////////////////////////////////////////////////
//淡入----逐渐变黑
/////////////////////////////////////////////////////////////////////
void FadeIn(int alpha, RECT rect, DWORD delay)
{
	int m_nAlpha = alpha - 1;
	DWORD otm;
	FastBlt(rect.left, rect.top, rect, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	while(m_nAlpha > 0)
	{
		otm=timeGetTime();
		BeginDirectDraw(DDS[SBuffer]);
		ImageAlpha(rect.left, rect.top, rect,pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], m_nAlpha, false, 0);
		EndDirectDraw(DDS[SBuffer]);
		UpdateScreen();
		m_nAlpha --;
		while(timeGetTime()-otm<delay)
			;
	}
	m_iScreenState=DCSS_FADEIN;
}

void FadeInRecover(int alpha, RECT rect, DWORD delay)
{
	if(m_iScreenState!=DCSS_FADEIN)
		return;
	int m_nAlpha = 1;
	DWORD otm;
	while(m_nAlpha < alpha)
	{
		otm=timeGetTime();
		BeginDirectDraw(DDS[SBuffer]);
		ImageAlpha(rect.left, rect.top, rect,pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], m_nAlpha, false, 0);
		EndDirectDraw(DDS[SBuffer]);
		UpdateScreen();
		m_nAlpha ++;
		while(timeGetTime()-otm<delay)
			;
	}
	m_iScreenState^=DCSS_FADEIN;
}

//////////////////////////////////////////////////////////////////////
//淡出
//////////////////////////////////////////////////////////////////////

void FadeOut(int alpha, RECT rect, DWORD delay)
{
	int m_nAlpha = 1;
	DWORD otm;
	FastBlt(rect.left, rect.top, rect, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	while(m_nAlpha < alpha)
	{
		otm=timeGetTime();
		BeginDirectDraw(DDS[SBuffer]);
		ImageAlpha(rect.left, rect.top, rect,pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], m_nAlpha, false, 0);
		EndDirectDraw(DDS[SBuffer]);
		UpdateScreen();
		m_nAlpha ++;
		while(timeGetTime()-otm<delay)
			;
	}
	m_iScreenState=DCSS_FADEOUT;
}

void FadeOutRecover(int alpha, RECT rect, DWORD delay)
{
	if(m_iScreenState!=DCSS_FADEOUT)
		return;
	int m_nAlpha = alpha - 1;
	DWORD otm;
	while(m_nAlpha > 0)
	{
		otm=timeGetTime();
		BeginDirectDraw(DDS[SBuffer]);
		ImageAlpha(rect.left, rect.top, rect,pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], m_nAlpha, false, 0);
		EndDirectDraw(DDS[SBuffer]);
		UpdateScreen();
		m_nAlpha --;
		while(timeGetTime()-otm<delay)
			;
	}
	m_iScreenState^=DCSS_FADEOUT;
}

void GraySurfaceRecover(RECT rect)
{
	FastBlt(rect.left, rect.top, rect, pS[SBuffer], pS[SBack], SP[SBuffer], SP[SBack], false, 0);
	UpdateScreen();
}
void GraySurface(RECT rect)
{
	FastBlt(rect.left, rect.top, rect, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	Gray(rect, pS[SBuffer], SP[SBuffer], false, 0);
	UpdateScreen();
}

void GammaIn(int color, int iGamma)
{
	if(iGamma>100)
		return;
	if(iGamma<0)
		iGamma=0;
	float dGamma=((float)(iGamma))/100;
	DDGAMMARAMP	ddGammaRamp;
	for(int i=0;i<256;i++)
	{
		if((color & 0x000f))
			ddGammaRamp.red[i]=(WORD)(ddGammaStart.red[i]*dGamma);
		else
			ddGammaRamp.red[i]=ddGammaStart.red[i];
		if((color & 0x00f0))
			ddGammaRamp.green[i]=(WORD)(ddGammaStart.green[i]*dGamma);
		else
			ddGammaRamp.green[i]=ddGammaStart.green[i];
		if((color & 0x0f00))
			ddGammaRamp.blue[i]=(WORD)(ddGammaStart.blue[i]*dGamma);
		else
			ddGammaRamp.blue[i]=ddGammaStart.blue[i];
	}	 
	lpDDGammaControl->SetGammaRamp(0,&ddGammaRamp);
	m_iScreenState=DCSS_GAMMA;
}
void GammaRestore()
{
	lpDDGammaControl->SetGammaRamp(0,&ddGammaStart);
	m_iScreenState^=DCSS_GAMMA;
}
int GetScreenState()
{
	return m_iScreenState;
}

void PlaneStagger(RECT rect, DWORD delay)
{
	FastBlt(rect.left, rect.top, rect, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	DDBLTFX ddBltFx;
	ddBltFx.dwSize=sizeof(DDBLTFX);
	ddBltFx.dwFillColor=0;
	DDS[SBuffer]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
	int i,j;
	RECT rect1;
	for(i = 0; i <= (rect.bottom-rect.top); i +=2)
	{
		j = i;
		while(( j > 0)&&(!bIsPassLogo))
		{
			rect1 = MakeRect(rect.left,rect.bottom - i+j-1,rect.right,rect.bottom - i+j);
			FastBlt(rect.left, rect.top+j-1, rect1, pS[SBuffer], pS[SBack], SP[SBuffer], SP[SBack], false, 0);
			rect1 = MakeRect(rect.left,rect.top+i - j, rect.right, rect.top+i - j+1 );
			FastBlt(rect.left, rect.bottom - j, rect1, pS[SBuffer], pS[SBack], SP[SBuffer], SP[SBack], false, 0);
			j -= 2;
		}
		UpdateScreen();
		Delay(delay);
	}
}
void RainDrop(RECT rect, DWORD delay)
{
	FastBlt(rect.left, rect.top, rect, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	DDBLTFX ddBltFx;
	ddBltFx.dwSize=sizeof(DDBLTFX);
	ddBltFx.dwFillColor=0;
	DDS[SBuffer]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
	int i,j;
	RECT rect1;
	for(i = 0; i < rect.bottom-rect.top; i ++)
	{
		for(j = 0; (j < rect.bottom-rect.top - i)&&(!bIsPassLogo); j ++)
		{
			rect1 = MakeRect(rect.left,rect.bottom - i,rect.right,rect.bottom - i+1);
			FastBlt(rect.left, rect.top+j, rect1, pS[SBuffer], pS[SBack], SP[SBuffer], SP[SBack], false, 0);
		}
		UpdateScreen();
		Delay(delay);
	}
}
void Shutter(RECT rect, DWORD delay)
{
	FastBlt(rect.left, rect.top, rect, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	DDBLTFX ddBltFx;
	ddBltFx.dwSize=sizeof(DDBLTFX);
	ddBltFx.dwFillColor=0;
	DDS[SBuffer]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
	int i,stepi,j;
	RECT rect1;
	stepi=(rect.bottom-rect.top)/10;
	for( i=0; i<=stepi; i++ )
	{
		for( j=0; (j<10)&&(!bIsPassLogo); j++ )
		{
			rect1 = MakeRect(rect.left,rect.top+j*stepi+i,rect.right,rect.top+j*stepi+i+1);
			FastBlt(rect.left, rect.top+j*stepi+i, rect1, pS[SBuffer], pS[SBack], SP[SBuffer], SP[SBack], false, 0);
		}
		UpdateScreen();
		Delay(delay);
	}
}

void BuildingBlock(RECT rect, DWORD delay)
{
	FastBlt(rect.left, rect.top, rect, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	DDBLTFX ddBltFx;
	ddBltFx.dwSize=sizeof(DDBLTFX);
	ddBltFx.dwFillColor=0;
	DDS[SBuffer]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
	int i,stepx,stepy,dispnum,j,x,y;
	int pxy[10][10];			// 使用本数组记录已显示过的数据组
	RECT rect1;
	for ( i=0; i<10; i++ )
		for ( j=0; j<10; j++ )
			pxy[i][j]=0;
	stepx=(rect.bottom-rect.top)/10;
	stepy=(rect.bottom-rect.top)/10;
	srand( (unsigned)GetTickCount());
	dispnum=0;
	// 记录已显示过的数据组的个数
	while(!bIsPassLogo)
	{
		x=rand() % 10;
		y=rand() % 10;
		if ( pxy[x][y] )		// 本组x,y所代表的数据组是否已显示过?
			continue;
		pxy[x][y]=1;			// 表明本组x,y所代表的数据组已显示过

		rect1 = MakeRect(rect.left+x*stepx, rect.top+y*stepy,rect.left+(x+1)*stepx, rect.top+(y+1)*stepy);
		FastBlt(rect.left+x*stepx, rect.top+y*stepy, rect1, pS[SBuffer], pS[SBack], SP[SBuffer], SP[SBack], false, 0);
		UpdateScreen();
		Delay(delay);
		dispnum++;
		if ( dispnum >=100 ) 
			break;
	}
}
short *pRipBuf1;
short *pRipBuf2;
BOOL  bRendering;


bool InitRippleData()
{
	SAFE_FREE(pRipBuf1);
	SAFE_FREE(pRipBuf2);
	pRipBuf1=new short[SCREEN_WIDTH*SCREEN_HEIGHT];
	RAM_ASSERT(pRipBuf1);
	pRipBuf2=new short[SCREEN_WIDTH*SCREEN_HEIGHT];
	RAM_ASSERT(pRipBuf2);
	memset(pRipBuf1,0,sizeof(short)*SCREEN_WIDTH*SCREEN_HEIGHT);
	memset(pRipBuf2,0,sizeof(short)*SCREEN_WIDTH*SCREEN_HEIGHT);
	return true;
}

void AddRippleSour(int cx,int cy,int nWeight,int nRad)
{
	if(cx+nRad>SCREEN_WIDTH || cy+nRad>SCREEN_HEIGHT || cx-nRad<0 || cy-nRad<0)
		return;
	int nSqrRad=nRad*nRad;
	for(int i=cx-nRad;i<cx+nRad;i++)
	{
		for(int j=cy-nRad;j<cy+nRad;j++)
		{
			if((i-cx)*(i-cx)+(j-cy)*(j-cy)<nSqrRad)					//是否在水波圆内
				pRipBuf1[SCREEN_WIDTH*j+i]=-nWeight;						//能量
		}
	}
}
void ComputeNextRipple()
{
	for(int i=SCREEN_WIDTH;i<SCREEN_WIDTH*(SCREEN_HEIGHT-1);i ++)
	{ 
		pRipBuf2[i]=((pRipBuf1[i-1]+pRipBuf1[i+1]+pRipBuf1[i-SCREEN_WIDTH]+pRipBuf1[i+SCREEN_WIDTH])>>1)-pRipBuf2[i]; 
		pRipBuf2[i]-=pRipBuf2[i]>>5;
	}
	short *pBufTmp=pRipBuf1;
	pRipBuf1=pRipBuf2;
	pRipBuf2=pBufTmp;
	if(memcmp(pRipBuf1,pRipBuf2,sizeof(short)*SCREEN_WIDTH*SCREEN_HEIGHT)==0)
		bRendering=false;
}
void RenderRipple()
{
	WORD *pBuf1=(WORD *)BeginDirectDraw(DDS[SBack]);
	WORD *pBuf2=(WORD *)BeginDirectDraw(DDS[SBuffer]);
	int cxOffsite;
	int cyOffsite;
	int cxReal;
	int cyReal;
	int index=SCREEN_WIDTH;
	for(int i=1;i<(SCREEN_HEIGHT-1);i++)
	{
		for(int j=0;j<SCREEN_WIDTH;j++)
		{
			cxOffsite=pRipBuf1[index-1]-pRipBuf1[index+1];
			cyOffsite=pRipBuf1[index-SCREEN_WIDTH]-pRipBuf1[index+SCREEN_WIDTH];
			cxReal=j+cxOffsite;
			cyReal=i+cyOffsite;
			if(cxReal<0 || cxReal>SCREEN_WIDTH || cyReal<0 || cyReal>SCREEN_HEIGHT)
			{
				index++;
				continue;
			}
			pBuf2[SCREEN_WIDTH*i+j]=pBuf1[SCREEN_WIDTH*cyReal+cxReal];
			index++;
		}
	}
	EndDirectDraw(DDS[SBack]);
	EndDirectDraw(DDS[SBuffer]);
}

void Ripple(int nPtCount,POINTS *ptStart,int *pWeight,int *pRad)
{
	RECT rect1;
	rect1 = MakeRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
	FastBlt(0, 0, rect1, pS[SBack], pS[SBuffer], SP[SBack], SP[SBuffer], false, 0);
	DDBLTFX ddBltFx;
	ddBltFx.dwSize=sizeof(DDBLTFX);
	ddBltFx.dwFillColor=0;
	DDS[SBuffer]->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
	if(!ptStart || !pWeight || !pRad || nPtCount<=0)
		return;
	if(!InitRippleData())
		return;
	for(int i=0;i<nPtCount;i++)
	{
		AddRippleSour(ptStart[i].x,ptStart[i].y,pWeight[i],pRad[i]);
	}
	bRendering=true;
	while((bRendering)&&(!bIsPassLogo))
	{
		ComputeNextRipple();
		RenderRipple();
		UpdateScreen();
	}
	SAFE_FREE(pRipBuf1);
	SAFE_FREE(pRipBuf2);
}